import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

class PlayerScore implements Comparable<PlayerScore> {
    String name;
    int score;
    String difficulty;
    Date date;

    public PlayerScore(String name, int score, String difficulty) {
        this.name = name;
        this.score = score;
        this.difficulty = difficulty;
        this.date = new Date();
    }

    @Override
    public int compareTo(PlayerScore o) {
        return Integer.compare(o.score, this.score);
    }
}

class ScoreManager {
    private static final String SCORE_FILE = "scores.dat";
    private List<PlayerScore> scores = new ArrayList<>();

    public ScoreManager() {
        loadScores();
    }

    private void loadScores() {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(SCORE_FILE))) {
            scores = (List<PlayerScore>) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            // 首次运行文件不存在是正常的
        }
    }

    public void addScore(PlayerScore score) {
        scores.add(score);
        Collections.sort(scores);
        saveScores();
    }

    private void saveScores() {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(SCORE_FILE))) {
            oos.writeObject(scores);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public List<PlayerScore> getTopScores(int count) {
        return scores.subList(0, Math.min(count, scores.size()));
    }
}

class GameEngine {
    private int targetNumber;
    private int maxAttempts;
    private AtomicInteger attempts = new AtomicInteger(0);
    private List<Integer> guessHistory = new ArrayList<>();
    private String difficulty;

    public void newGame(String difficulty) {
        this.difficulty = difficulty;
        switch (difficulty) {
            case "Easy": 
                targetNumber = new Random().nextInt(50) + 1;
                maxAttempts = 10;
                break;
            case "Medium":
                targetNumber = new Random().nextInt(100) + 1;
                maxAttempts = 15;
                break;
            case "Hard":
                targetNumber = new Random().nextInt(200) + 1;
                maxAttempts = 20;
                break;
        }
        attempts.set(0);
        guessHistory.clear();
    }

    public Map<String, Object> makeGuess(int guess) {
        Map<String, Object> result = new HashMap<>();
        guessHistory.add(guess);
        int currentAttempt = attempts.incrementAndGet();

        if (guess == targetNumber) {
            result.put("status", "win");
            result.put("score", calculateScore());
            return result;
        }

        String hint = generateHint(guess);
        result.put("status", "continue");
        result.put("hint", hint);
        result.put("remaining", maxAttempts - currentAttempt);
        return result;
    }

    private int calculateScore() {
        int baseScore;
        switch (difficulty) {
            case "Easy": baseScore = 1000; break;
            case "Medium": baseScore = 2000; break;
            case "Hard": baseScore = 3000; break;
            default: baseScore = 1000;
        }
        return baseScore * (maxAttempts - attempts.get() + 1);
    }

    private String generateHint(int guess) {
        int difference = Math.abs(guess - targetNumber);
        if (difference == 0) return "精确命中！";
        if (difference <= 5) return "灼热！近在咫尺！";
        if (difference <= 15) return "非常接近！";
        if (difference <= 30) return "温度适中";
        return "寒冷...继续努力";
    }

    public int getTargetNumber() {
        return targetNumber;
    }

    public List<Integer> getGuessHistory() {
        return new ArrayList<>(guessHistory);
    }

    public int getRemainingAttempts() {
        return maxAttempts - attempts.get();
    }
}

public class AdvancedGuessGame extends JFrame {
    private GameEngine engine = new GameEngine();
    private ScoreManager scoreManager = new ScoreManager();
    
    private JComboBox<String> difficultyCombo = new JComboBox<>(new String[]{"Easy", "Medium", "Hard"});
    private JTextField guessField = new JTextField(10);
    private JTextArea infoArea = new JTextArea(10, 30);
    private JButton startButton = new JButton("新游戏");
    private JButton guessButton = new JButton("猜！");

    public AdvancedGuessGame() {
        initUI();
        setupListeners();
    }

    private void initUI() {
        setTitle("高级猜数字游戏");
        setLayout(new BorderLayout());
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        JPanel controlPanel = new JPanel();
        controlPanel.add(new JLabel("难度级别:"));
        controlPanel.add(difficultyCombo);
        controlPanel.add(startButton);
        controlPanel.add(new JLabel("你的猜测:"));
        controlPanel.add(guessField);
        controlPanel.add(guessButton);

        infoArea.setEditable(false);
        add(controlPanel, BorderLayout.NORTH);
        add(new JScrollPane(infoArea), BorderLayout.CENTER);

        pack();
        setLocationRelativeTo(null);
        updateGameState(false);
    }

    private void setupListeners() {
        startButton.addActionListener(e -> {
            engine.newGame((String) difficultyCombo.getSelectedItem());
            updateGameState(true);
            infoArea.setText("新游戏开始！目标范围：1-" + 
                (difficultyCombo.getSelectedIndex() == 0 ? 50 : 
                 difficultyCombo.getSelectedIndex() == 1 ? 100 : 200) + "\n");
        });

        guessButton.addActionListener(e -> new Thread(() -> {
            try {
                int guess = Integer.parseInt(guessField.getText());
                Map<String, Object> result = engine.makeGuess(guess);
                
                SwingUtilities.invokeLater(() -> {
                    if ("win".equals(result.get("status"))) {
                        JOptionPane.showMessageDialog(this, "恭喜！得分: " + result.get("score"));
                        saveScore((Integer) result.get("score"));
                        updateGameState(false);
                    } else {
                        infoArea.append("尝试 #" + engine.getGuessHistory().size() + 
                                      ": " + guess + " → " + result.get("hint") + 
                                      "\n剩余次数: " + result.get("remaining") + "\n");
                        if (engine.getRemainingAttempts() <= 0) {
                            JOptionPane.showMessageDialog(this, "游戏结束！正确答案是：" + engine.getTargetNumber());
                            updateGameState(false);
                        }
                    }
                    guessField.setText("");
                });
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(this, "请输入有效数字！");
            }
        }).start());
    }

    private void saveScore(int score) {
        String name = JOptionPane.showInputDialog(this, "请输入你的名字：");
        if (name != null && !name.trim().isEmpty()) {
            scoreManager.addScore(new PlayerScore(
                name.trim(), score, 
                (String) difficultyCombo.getSelectedItem()
            ));
            showHighScores();
        }
    }

    private void showHighScores() {
        List<PlayerScore> topScores = scoreManager.getTopScores(5);
        StringBuilder sb = new StringBuilder("🏆 高分榜：\n");
        for (int i = 0; i < topScores.size(); i++) {
            PlayerScore score = topScores.get(i);
            sb.append(String.format("%d. %s - %d (%s) [%tF]%n",
                    i + 1, score.name, score.score, score.difficulty, score.date));
        }
        JOptionPane.showMessageDialog(this, sb.toString());
    }

    private void updateGameState(boolean running) {
        guessField.setEnabled(running);
        guessButton.setEnabled(running);
        startButton.setEnabled(!running);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new AdvancedGuessGame().setVisible(true);
        });
    }
}